package com.bbz.crawler.ip.proxy.pool.core.validation.thread;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;

import com.bbz.crawler.ip.proxy.pool.core.model.CrawlerProxyIp;
import com.bbz.crawler.ip.proxy.pool.service.ICrawlerProxyIpService;
import com.bbz.crawler.ip.proxy.pool.service.impl.CrawlerProxyIpServiceImpl;
import com.xxl.job.core.log.XxlJobLogger;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;

public class ValidationThread implements Callable<List<Integer>> {
	private String threadName;
	private List<CrawlerProxyIp> crawlerProxyIpList;
	private int start;
	private int end;
	private List<Integer> ids = new ArrayList<>();
	private static final String requestIp = "https://www.zhihu.com/";
	@Autowired
	ICrawlerProxyIpService crawlerProxyIpService;

	public ValidationThread(String threadName, List<CrawlerProxyIp> crawlerProxyIpList, int start, int end) {
		this.threadName = threadName;
		this.crawlerProxyIpList = crawlerProxyIpList;
		this.start = start;
		this.end = end;
	}

	private static boolean isHostConnectable(CrawlerProxyIp crawlerProxyIp) {
		Socket socket = new Socket();
		try {
			socket.setSoTimeout(3000);// 设置读操作超时时间3 s
			socket.connect(new InetSocketAddress(crawlerProxyIp.getIp(), Integer.parseInt(crawlerProxyIp.getPort())));
		} catch (IOException e) {
			XxlJobLogger.log("ProxyIpValidation-JOB ,Connect Proxy IP Error:" + crawlerProxyIp.getIp());
			return false;
		} finally {
			try {
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return true;
	}

	private void CheckIp(CrawlerProxyIp crawlerProxyIp, boolean isHostConn) {
		if (isHostConn) {
			// 设置代理IP、端口、协议（请分别替换）
			HttpHost proxy = new HttpHost(crawlerProxyIp.getIp(), Integer.parseInt(crawlerProxyIp.getPort()));

			// 把代理设置到请求配置
			RequestConfig defaultRequestConfig = RequestConfig.custom().setProxy(proxy).build();
			// 实例化CloseableHttpClient对象
			CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
			HttpGet httpGet = new HttpGet(requestIp);
			httpGet.setHeader("User-Agent",
					"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36");
			CloseableHttpResponse httpResp = null;
			try {
				// 请求返回
				httpResp = httpclient.execute(httpGet);
				int statusCode = httpResp.getStatusLine().getStatusCode();
				if (statusCode == HttpStatus.SC_OK) {
					XxlJobLogger.log("ProxyIpValidation-JOB ,Check IP Available" + crawlerProxyIp.getIp());
					crawlerProxyIp.setFlage(0);
					crawlerProxyIp.setValidaDate(DateUtil.now());
					crawlerProxyIpService.updateById(crawlerProxyIp);
				} else {
					XxlJobLogger.log("ProxyIpValidation-JOB ,Check IP Failure" + crawlerProxyIp.getIp() + "/ statusCode"
							+ statusCode);
				}
			} catch (Exception e) {
				ids.add(crawlerProxyIp.getId());
				XxlJobLogger.log("ProxyIpValidation-JOB ,Check Failure Time Out IP:" + crawlerProxyIp.getIp());
			}
		} else {
			ids.add(crawlerProxyIp.getId());
		}

	}

	@Override
	public List<Integer> call() throws Exception {
		CrawlerProxyIp crawlerProxyIp = null;
		boolean isHostConn = false;
		List<CrawlerProxyIp> subList = crawlerProxyIpList.subList(start, end);
		for (int i = 0, length = subList.size(); i < length; i++) {
			crawlerProxyIp = subList.get(i);
			isHostConn = isHostConnectable(crawlerProxyIp);
			CheckIp(subList.get(i), isHostConn);
			System.out.println(threadName + "-Check IP" + crawlerProxyIp.getIp());
		}
		return ids;
	}
}
